<?php

namespace Modules\Agent\Entities;

use Modules\Core\Entities\BaseEntity as Model;
use Modules\User\Entities\User;
use ThrowException;
use Setting; 
use DB;

class Brokerage extends Model
{
    protected $guarded = [];
    protected $table = 'brokerage_records';
    static public $resourceName = '';

    protected $appends = ['union_status', 'union_status_text'];

    public function user()
    {
        return $this->belongsTo('\Modules\User\Entities\User', 'user_id');
    }

    public function order()
    {
        return $this->belongsTo('\Modules\Order\Entities\BaseOrder', 'order_id');
    }

    public function order_sku()
    {
        return $this->belongsTo('\Modules\Order\Entities\OrderSku', 'order_sku_id');
    }

    // 一级分销
    public function order_user()
    {
        return $this->belongsTo('\Modules\User\Entities\User', 'order_user_id');
    }

    public function getUnionStatusAttribute()
    {
        // $status = $this->returnUnionStatus();
        // if ($status)
        //     return $status;
        $map = [
            0 => 'pending',
            1 => 'completed',
            2 => 'closed'
        ];

        return $map[$this->status];
    }

    public function getUnionStatusTextAttribute()
    {
        // $status = $this->returnUnionStatus();
        // if ($status)
        //     return $status;
        $map = [
            'pending' => '待确认',
            'completed' => '已发放',
            'closed' => '已取消'
        ];

        return $map[$this->union_status];
    }

    public function scopeSearch($query, $key)
    {
        return $query->whereHas('order_user', function ($query) use ($key) {
            return $query->where('phone', $key)->orWhere('name', 'like', '%'.$key.'%');
        })->orWhereHas('user', function ($query) use ($key) {
            return $query->where('phone', $key)->orWhere('name', 'like', '%'.$key.'%');
        })->orWhereHas('order_sku', function ($query) use ($key) {
            return $query->where('title', 'like', '%'.$key.'%')->orWhere('order_number', $key);
        });
    }

    // 状态筛选
    public function scopeStatus($query, $status)
    {
        $map = [
            'pending' => [
                'status' => 0
            ],
            'completed'  => [
                'status' => 1
            ],
            'closed' => [
                'status' => 2
            ]
        ];

        $where = @$map[$status] ?: [];

        return $query->where($where);
    }

    static public function beforeGetList($options)
    {
        if (@$options['status']) {
            $options['scopes']['status'] = $options['status'];
        }

        if (@$options['inviter_phone']) {
            $inviter = User::where('phone', $options['inviter_phone'])->first();
            $options['where']['user_id'] = @$inviter->id ?: 0;
        }

        return $options;
    }


    // 计算一件商品的佣金
    // brokerageType   direct\直接上级佣金   indirect\间接上级佣金   leader\团队长佣金
    static public function getSkuableBrokerage($orderSku, $user, $brokerageType) 
    {
        $baseSku = $orderSku->base_sku_;

        if (!$baseSku) {
            return false;
        } 

        $node = $baseSku->getNodeEntity();

        if (!$node) {
            return false;
        }

        // 无绑定的分销等级
        if (!$user->agent_level) {
            return false;
        }

        // 佣金率设置
        $brokerageSetting = $user->agent_level->brokerage_setting ?: [];

        $setting = collect($brokerageSetting)->where('node_type', $node->getType('node_type'))->first();

        // 没有设置， 或者设置为不开启，则没有佣金
        if (!$setting || !$setting['is_enabled']) {
            return false;
        }

        $totalMoneyPrice = $orderSku->discount_money_price * $orderSku->total;
        $totalScorePrice = $orderSku->discount_score_price * $orderSku->total;

        // 佣金率
        if ($brokerageType === 'direct') {
            // 直接邀请
            $moneyRatio = @$setting['direct_money_ratio'] ?: 0;
            $scoreRatio = @$setting['direct_score_ratio'] ?: 0;
        }
        elseif ($brokerageType === 'indirect') {
            // 非直接邀请
            $moneyRatio = @$setting['indirect_money_ratio'] ?: 0;
            $scoreRatio = @$setting['indirect_score_ratio'] ?: 0;
        }
        elseif ($brokerageType === 'leader') {
            // 团队长
            $moneyRatio = @$setting['leader_money_ratio'] ?: 0;
            $scoreRatio = @$setting['leader_score_ratio'] ?: 0;
        }


        // 人民币与积分佣金
        $money = floor($moneyRatio / 100 * $totalMoneyPrice);
        $score = floor($scoreRatio / 100 * $totalScorePrice);

        $moneyLimit = @$setting['money_max_limit'];
        $scoreLimit = @$setting['score_max_limit'];

        // 人民币佣金最大限制
        if ($moneyLimit) {
            $money = min([$moneyLimit * $orderSku->total, $money]);
        }

        // 积分佣金最大限制
        if ($scoreLimit) {
            $score = min([$scoreLimit * $orderSku->total, $score]);
        }

        $res = [
            'money' => $money,
            'score' => $score,
            'money_ratio' => $moneyRatio,
            'score_ratio' => $scoreRatio,
            'money_limit' => $moneyLimit,
            'score_limit' => $scoreLimit,
        ];

        return $res;
    }

    // brokerageType   direct\直接上级佣金   indirect\间接上级佣金   leader\团队长佣金
    static public function createWithOrderSku($orderSku, $orderUser, $inviter, $brokerageType)
    {
        // 分销员的分销状态已禁用
        if (!$inviter->agent_status) {
            return false;
        }

        // 检查分销等级是否可以更新
        $inviter->checkAgentLevelUpdate();

        $order = $orderSku->order;

        $brokerage = static::getSkuableBrokerage($orderSku, $inviter, $brokerageType);

        // \Log::error($brokerage);

        $money = @$brokerage['money'];
        $score = @$brokerage['score'];

        if (!$brokerage || (!$money && !$score)) {
            return false;
        }

        $info = [
            'user_id' => $inviter->id,
            'order_id' => $order->id,
            'order_number' => $order->number,
            'order_user_id' => $orderUser->id,
            'order_sku_id' => $orderSku->id,
            'brokerage_type' => $brokerageType,
            'money' => $money,
            'score' => $score,
            'invite_level' => $brokerageType === 'direct' ? 0 : 1,
            'order_type' => $order->type,
            'order_paid_at' => $order->money_paid_at ?: $order->score_paid_at,
            'node_type' => $orderSku->node_type,
            'node_id' => $orderSku->node_id,
            'node_uuid' => $orderSku->node_uuid,
            'activity_type' => $orderSku->activity_type,
            'activity_id' => $orderSku->activity_id,
            'activity_uuid' => $orderSku->activity_uuid,
            'money_ratio' => @$brokerage['money_ratio'],
            'score_ratio' => @$brokerage['score_ratio'],
        ];

        $item = self::create($info);

        return $item;
    }

    static public function createWith($order)
    {
        $orderTypes = ['product', 'activity'];

        $orderUser = $order->user;

        // 不在目标内的订单和没有邀请人的订单，不需要发放佣金
        // 没有支付
        $noPayFlag = !$order->pay_money_price && !$order->pay_score_price &&  !$order->redpack_discount && !$order->score_used;

        // 更新用户累计消费总额
        if (!$noPayFlag) {
            $orderUser->update([
                'paid_money_total' => $orderUser->paid_money_total + $order->product_money_price,
                'paid_score_total' => $orderUser->paid_score_total + $order->product_score_price
            ]);
        }

        // 没有邀请人或邀请人被拉黑
        if (!$orderUser->inviter || $orderUser->inviter->isBlocked()) {
            // 无佣金 
            $order->update([
                'brokerage_status' => 1
            ]);
            return null;
        }

        // 判断是否设置佣金有效期并且是否已超出有效期
        $brokerageTimeout = @Setting::get('sys_invite')['brokerage_timeout'] ?: 0;
        if ($brokerageTimeout) {
            if (strtotime('-' . $brokerageTimeout . '  hours') > strtotime($orderUser->invited_at)) {
                $order->update([
                    'brokerage_status' => 1
                ]);
                return null;
            }
        }


        // 订单类型无佣金 或 订单无支付
        if (!in_array($order->type, $orderTypes) || $noPayFlag) {
            // 无佣金 
            $order->update([
                'brokerage_status' => 1
            ]);
            return null;
        }

        $directInviter = $orderUser->inviter;

        // 擂台玩法 空空奖 pk奖  两种玩法剔除
        if ( $order->node_type == 'leitai' && !$directInviter->isAgentLeaderDIY556() ){
            $activity = \Modules\Activity\Entities\Leitai\Activity::where("uuid", $order->node_uuid)->first();
            if ( !$activity ){
                $order->update([
                    'brokerage_status' => 7
                ]);
                return null;
            }

            if ( $directInviter->isAgentLeaderDIY() ){
                // 自定义的佣金等级 555  擂台玩法仅统计 空空奖&PK奖
                if ( !in_array($activity->play_type, [4, 5]) ){
                    $order->update([
                        'brokerage_status' => 1
                    ]);
                    return null;
                }
            }else{
                // 非自定义的佣金等级 555  擂台玩法排除统计 空空奖&PK奖
                if ( in_array($activity->play_type, [4, 5, 7]) ){
                    $order->update([
                        'brokerage_status' => 1
                    ]);
                    return null;
                }
            }
        }

        $brokerageList = [];

        // 直接上级创建记录
        if ($directInviter && !$directInviter->isAgentLeader()) {
            foreach ($order->skus as $orderSku) {
                $item = static::createWithOrderSku($orderSku, $orderUser, $directInviter, 'direct');

                if ($item) {
                    array_push($brokerageList, $item);
                }
            }

            // 更新直接上级的佣金结算
            $directInviter->updateMyBrokerage();
        }

        // 上上级记录
        $indirectInviter = $directInviter->inviter;
        if ($indirectInviter && !$indirectInviter->isAgentLeader()) {
            foreach ($order->skus as $orderSku) {
                $item = static::createWithOrderSku($orderSku, $orderUser, $indirectInviter, 'indirect');

                if  ($item) {
                    array_push($brokerageList, $item);
                }
            }

            // 更新间接上级的佣金结算
            $indirectInviter->updateMyBrokerage();
        }


        // 团队长的订单
        $agentLeader = $orderUser->getAgentLeader();
        if ($agentLeader) {
            // 有团队长，则创建团队长的销售记录
            foreach ($order->skus as $orderSku) {
                $item = static::createWithOrderSku($orderSku, $orderUser, $agentLeader, 'leader');
            }
        }


        // 更新用户贡献的佣金
        $orderUser->updateBrokerage();

        // 没有佣金记录
        if (count($brokerageList) === 0) {
            $order->update([
                'brokerage_status' => 1
            ]);
            return null;
        }
        else {
            $order->update([
                'brokerage_status' => 2
            ]);
        }
    }

    // 订单取消
    public function close()
    {
        if ($this->status !== 0) {
            return false;
        }
        
        $this->update([
            'status' => 2
        ]);

        // 更新用户贡献的佣金
        $this->order_user->updateBrokerage();
    }

    public function tryComplete()
    {
        // 不是待处理状态
        if ($this->status !== 0) {
            return false;
        }

        // 订单是否已完成
        if ($this->order->status === 9) {
            $this->complete();
        }
    }

    // 发放推广返佣
    public function complete()
    {
        // 只有待确认才能发放收益
        if ($this->status !== 0) {
            return false;
        }

        DB::beginTransaction();

        $desc = '分销佣金(' . $this->order_sku->title . $this->order_sku->id . ')';

        // 人民币佣金
        if ($this->money) {
            $this->user->asset('redpack')->in($this->money, [
                'description' => $desc
            ]);
        }

        // 积分佣金
        if ($this->score) {
            $this->user->asset('score')->in($this->score, [
                'description' => $desc
            ]);
        }

        $this->update([
            'status' => 1,
            'completed_at' => now()
        ]);

        // 订单标记为已发放佣金
        // $this->order->update([
        //     'brokerage_status' => 3
        // ]);

        DB::commit();
    }
}
